﻿/* Copyright 2007-2008 dnAnalytics Project.
 *
 * Contributors to this file:
 * Marcus Cuda
 *
 * This file is part of dnAnalytics.  dnAnalytics is licensed under the 
 * Microsoft Public License. See License.txt for a complete copy of the
 * license.
 */

namespace dnAnalytics.Random
{
    /// <summary>
    /// A 32-bit combined multiple recursive generator with 2 components of order 3.
    /// </summary>
    public partial class Mrg32k3a
    {
        private readonly MklRandomNumberGenerator mRng;

        /// <summary>
        /// Initializes a new instance of the <see cref="Mrg32k3a"/> class.
        /// </summary>
        /// <param name="seed">The seed value.</param>
        /// <remarks>Uses the value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to
        /// set whether the instance is thread safe.</remarks>        
        public Mrg32k3a(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
        {
            mRng = new MklRandomNumberGenerator(MklRngMethod.VSL_BRNG_MRG32K3A, seed);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Mrg32k3a"/> class.
        /// </summary>
        /// <param name="seed">The seed value.</param>
        /// <param name="threadSafe">if set to <c>true</c>, the class is thread safe.</param>
        public Mrg32k3a(int seed, bool threadSafe) : base(threadSafe)
        {
            mRng = new MklRandomNumberGenerator(MklRngMethod.VSL_BRNG_MRG32K3A, seed);
        }
        
        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            mRng.Dispose();
        }

        #endregion

        /// <summary>
        /// Returns a random number between 0.0 and 1.0.
        /// </summary>
        /// <returns>
        /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
        /// </returns>
        protected override double DoSample()
        {
            return mRng.Sample();
        }
    }
}